home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- *
- * a new FSEL placed in public domain by D N Korte 26 Dec 86.
- * Do with it whatever you want...
- *
- * modified for undelete program & GNU c by T Blight, Dec 1992
- *
- *****************************************************************/
-
- #include <aesbind.h>
- #include <gemfast.h>
- #include <osbind.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <errno.h>
- #include "undel.h"
-
- #define QUIT 0
- #define CONTINUE 1
-
- #define MAXFILES 144 /* abs max 327 (overflow FS_calc_curfirst) */
- #define WINDSIZE 9 /* size of file window */
- #define DIAMOND_THINGY 7
-
- /*** indexes into rs_object ***/
- #define CANCBUT 2
- #define OKBUT 3
- #define NEWNAME 4
- #define WINDOW 5
- #define DRVA 6
- #define DRVB 7
- #define DRVC 8
- #define DRVD 9
- #define DRVE 10
- #define DRVF 11
- #define SLEXTN0 12
- #define SLEXTN1 13
- #define SLEXTN2 14
- #define SLEXTN3 15
- #define SLEXTN4 16
- #define EXTN3 17
- #define EXTN4 18
- #define FNAM1 19
- #define FNAM2 20
- #define FNAM3 21
- #define FNAM4 22
- #define FNAM5 23
- #define FNAM6 24
- #define FNAM7 25
- #define FNAM8 26
- #define FNAM9 27
- #define FILEBOX 28
- #define TOPBAR 29
- #define UARROW 30
- #define SLIDBOX 31
- #define MVSLIDE 32
- #define DARROW 33
- #define TOPTEXT 34
-
- struct finfo {
- char name[9]; /* name of file */
- char extn[4]; /* extension of it */
- BOOL dirflag; /* FALSE if not a directory, TRUE if is directory */
- };
-
- PRIVATE void FS_dir_dis( struct finfo[], int[], int, int);
- PRIVATE void FS_dir_select_good( int, const char *, const char *, const char *,
- char *, char *, struct finfo[], int, int[],
- int *, int *);
- PRIVATE int FS_dir_read(char *drivs, char *path, struct finfo files[],
- int *numfiles, char *dispath);
- PRIVATE void FS_shift_curfirst(int, int, int *);
- PRIVATE void FS_calc_curfirst(int, int, int *);
- PRIVATE void FS_calc_slid_box(int, int, BOOL);
- PRIVATE void FS_setname( int, char *);
- PRIVATE void FS_path_lengthen( char *, int, struct finfo[], char *);
- PRIVATE void FS_path_shorten( char *, char *);
- PRIVATE void FS_pathtrunc( char *, const char *);
- PRIVATE BOOL FS_wildmatch( const char *, const char *);
- PRIVATE void FS_exchinfo( struct finfo *, struct finfo *);
- PRIVATE int FS_find_last_delim(char, char *);
- PRIVATE void FS_strxcpy(char *, const char*);
-
-
-
- PRIVATE char file_ids[WINDSIZE][17]; /* spot for (10) 16-char formatted filenames in menu */
-
- PRIVATE TEDINFO rs_tedinfo[] = {
- NULL,"________.___","FFFFFFFFFFF",3,0,0,0x1180,0, 0,0,13, /* 0 for newname */
- NULL,".___", "", 3,0,2,0x1180,0,-2,0,5, /* 1 for extn0 */
- NULL,".___", "", 3,0,2,0x1180,0,-2,0,5, /* 2 for extn1 */
- NULL,".___", "", 3,0,2,0x1180,0,-2,0,5, /* 3 for extn2 */
- NULL,".___", "FFF", 3,0,2,0x1180,0,-2,0,5, /* 4 for extn3 */
- NULL,".___", "FFF", 3,0,2,0x1180,0,-2,0,5, /* 5 for extn4 */
- NULL,"", "", 3,0,2,0x1180,0, 0,0,0 /* 6 for pathname in TOPBAR */
- };
- /* ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
- | | | | | | | | | | +-- te_tmplen length of template (+1 for null)
- | | | | | | | | | ----- te_txtlen length of text (+1 for null)
- | | | | | | | | +------ te_thickness border thickness (-) outside
- | | | | | | | +--------- te_junk2
- | | | | | | +-------------- te_color packed color information
- | | | | | +------------------ te_just 0=left 1=right 2=centered
- | | | | +-------------------- te_junk1
- | | | +---------------------- te_font 3=system 5=small
- | | +------------------------------- *te_pvalid ptr to validation chars
- | +---------------------------------------------- *te_ptmplt ptr to template
- +------------------------------------------------------- *te_ptext ptr to text
- */
-
- PRIVATE OBJECT rs_object[] = {
- -1,1,34,G_BOX, NONE, OUTLINED, 0x21100L, 0, 0,38,15, /* 0 dialog box */
- 2,-1,-1,G_STRING, NONE, NORMAL, 0L, 2, 1,34,1, /* 1 TITLE */
- 3,-1,-1,G_BUTTON, SELECTABLE|EXIT, NORMAL,(unsigned long)"CANCEL",22, 3, 6,1, /* 2 CANCBUT */
- 4,-1,-1,G_BUTTON, SELECTABLE|EXIT|DEFAULT, NORMAL,(unsigned long)"OK",30, 3, 6,1, /* 3 OKBUT */
- 5,-1,-1,G_FTEXT, EDITABLE, NORMAL,(unsigned long)&rs_tedinfo[0],22, 5,12,1, /* 4 NEWNAME */
- 6,-1,-1,G_IBOX, NONE, NORMAL, 0xFF1100L, 2, 3,18,11, /* 5 WINDOW (outline of pretend window) */
- 7,-1,-1,G_BUTTON, SELECTABLE|EXIT|RBUTTON, NORMAL,(unsigned long)"A:",22, 7, 4,1, /* 6 DRVA */
- 8,-1,-1,G_BUTTON, SELECTABLE|EXIT|RBUTTON, NORMAL,(unsigned long)"B:",27, 7, 4,1, /* 7 DRVB */
- 9,-1,-1,G_BUTTON, SELECTABLE|EXIT|RBUTTON, NORMAL,(unsigned long)"C:",32, 7, 4,1, /* 8 DRVC */
- 10,-1,-1,G_BUTTON, SELECTABLE|EXIT|RBUTTON, NORMAL,(unsigned long)"D:",22, 9, 4,1, /* 9 DRVD */
- 11,-1,-1,G_BUTTON, SELECTABLE|EXIT|RBUTTON, NORMAL,(unsigned long)"E:",27, 9, 4,1, /* 10 DRVE */
- 12,-1,-1,G_BUTTON, SELECTABLE|EXIT|RBUTTON, NORMAL,(unsigned long)"F:",32, 9, 4,1, /* 11 DRVF */
- 13,-1,-1,G_FBOXTEXT,SELECTABLE|TOUCHEXIT, NORMAL,(unsigned long)&rs_tedinfo[1],22,11, 4,1, /* 12 SLEXTN0 */
- 14,-1,-1,G_FBOXTEXT,SELECTABLE|TOUCHEXIT, NORMAL,(unsigned long)&rs_tedinfo[2],27,11, 4,1, /* 13 SLEXTN1 */
- 15,-1,-1,G_FBOXTEXT,SELECTABLE|TOUCHEXIT, NORMAL,(unsigned long)&rs_tedinfo[3],32,11, 4,1, /* 14 SLEXTN2 */
- 16,-1,-1,G_BOX, SELECTABLE|TOUCHEXIT, NORMAL, 0xFE1100L,22,13, 2,1, /* 15 SLEXTN3 */
- 17,-1,-1,G_BOX, SELECTABLE|TOUCHEXIT, NORMAL, 0xFE1100L,30,13, 2,1, /* 16 SLEXTN4 */
- 18,-1,-1,G_FBOXTEXT,EDITABLE, NORMAL,(unsigned long)&rs_tedinfo[4],24,13, 4,1, /* 17 EXTN3 */
- 28,-1,-1,G_FBOXTEXT,EDITABLE, NORMAL,(unsigned long)&rs_tedinfo[5],32,13, 4,1, /* 18 EXTN4 */
- 20,-1,-1,G_STRING, SELECTABLE|TOUCHEXIT|RBUTTON,NORMAL,(unsigned long)&file_ids[0][0], 0, 0,15,1, /* 19 FNAM1 (note that for doubleclick */
- 21,-1,-1,G_STRING, SELECTABLE|TOUCHEXIT|RBUTTON,NORMAL,(unsigned long)&file_ids[1][0], 0, 1,15,1, /* 20 FNAM2 (to work, these objects must */
- 22,-1,-1,G_STRING, SELECTABLE|TOUCHEXIT|RBUTTON,NORMAL,(unsigned long)&file_ids[2][0], 0, 2,15,1, /* 21 FNAM3 (be G_STRING and must have */
- 23,-1,-1,G_STRING, SELECTABLE|TOUCHEXIT|RBUTTON,NORMAL,(unsigned long)&file_ids[3][0], 0, 3,15,1, /* 22 FNAM4 (ob_flags exactly as shown. */
- 24,-1,-1,G_STRING, SELECTABLE|TOUCHEXIT|RBUTTON,NORMAL,(unsigned long)&file_ids[4][0], 0, 4,15,1, /* 23 FNAM5 (When selected, bit 15 of */
- 25,-1,-1,G_STRING, SELECTABLE|TOUCHEXIT|RBUTTON,NORMAL,(unsigned long)&file_ids[5][0], 0, 5,15,1, /* 24 FNAM6 (form_do return will be */
- 26,-1,-1,G_STRING, SELECTABLE|TOUCHEXIT|RBUTTON,NORMAL,(unsigned long)&file_ids[6][0], 0, 6,15,1, /* 25 FNAM7 (set if gotten by a */
- 27,-1,-1,G_STRING, SELECTABLE|TOUCHEXIT|RBUTTON,NORMAL,(unsigned long)&file_ids[7][0], 0, 7,15,1, /* 26 FNAM8 (doubleclick. */
- 28,-1,-1,G_STRING, SELECTABLE|TOUCHEXIT|RBUTTON,NORMAL,(unsigned long)&file_ids[8][0], 0, 8,15,1, /* 27 FNAM9 */
- 29,19,27,G_BOX, NONE, NORMAL, 0x011100L, 2, 4,15,10, /* 28 FILEBOX (box is parent for FNAMs) */
- 30,-1,-1,G_BOX, NONE, NORMAL, 0xFF1121L, 2, 3,18,1, /* 29 TOPBAR */
- 31,-1,-1,G_BOXCHAR, TOUCHEXIT, NORMAL, 0x01011180L,17, 4, 3,1, /* 30 UARROW (adjust y later) */
- 33,32,32,G_BOX, TOUCHEXIT, NORMAL, 0x011111L,17, 5, 3,7, /* 31 SLIDBOX (adjust y later) */
- 31,-1,-1,G_BOX, TOUCHEXIT, NORMAL, 0x011100L, 0, 0, 3,1, /* 32 MVSLIDE */
- 34,-1,-1,G_BOXCHAR, TOUCHEXIT, NORMAL, 0x02011100L,17,12, 3,1, /* 33 DARROW (adjust y and h later) */
- 0,-1,-1,G_TEXT, LASTOB, NORMAL, (unsigned long)&rs_tedinfo[6], 3, 3,16,1 /* 34 TOPTEXT */
- };
- /* ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
- | | | | | | | | | | +-- ob_height height of obj (now chars, but
- | | | | | | | | | +---- ob_width width of obj (must cnvt to pixels
- | | | | | | | | +------- ob_y y coord relative to parent
- | | | | | | | +---------- ob_x x coord relative to parent
- | | | | | | +--------------------- ob_spec obj determines meaning (p11-55,60)
- | | | | | +------------------------------ ob_state current state of obj (p.11-61 MM)
- | | | | +----------------------------------------------------------- ob_flags attributes for obj (p.11-60 MM)
- | | | +----------------------------------------------------------------------- ob_type object type (p. 11-59 MM)
- | | +---------------------------------------------------------------------------- ob_tail ptr to last child of obj or -1
- | +------------------------------------------------------------------------------ ob_head ptr to first child of obj or -1
- +--------------------------------------------------------------------------------- ob_next ptr to next sibling or -1
-
- */
-
- PRIVATE int xdial,ydial,wdial,hdial; /* co-ord for dialog box */
-
- PRIVATE int firstcall = TRUE; /* for first-run initialization */
-
- /*************************************************************************
- *
- * Function fsel ()
- * This is what we're here for !!!
- * Can't say much more 'cuz MM editor is almost full of characters.
- *
- * The parameters are as follows:
- *
- * stat an integer returned by routine; 0=canc 1=ok
- * title a string of up to 34 characters which will
- * be displayed as the title or instructions line
- * path a string representing the current path.
- * This must both start and end with a '\' and
- * may include any number of subdirectories
- * within it. The selector will return the
- * user's path selection in this variable too
- * so it should be a real variable of reasonable
- * length (don't make it up as text in the
- * parameter list itself!).
- * driv An integer indicating which drive to use.
- * code is as follows;
- * -1 use current default drive
- * 0 A:
- * 1 B:
- * ...
- * 5 F:
- * The selector will return the user's drive
- * selection in this variable too, so you should
- * pass the address instead of the value.
- * sextn An integer which indicates which of the five
- * extension boxes should be used when matching
- * filenames. This is bit-mapped such that:
- * 0x0001 selects extn0
- * 0x0002 selects extn1
- * 0x0004 selects extn2
- * 0x0008 selects extn3
- * 0x0010 selects extn4
- * More than one may be selected. As above, the
- * selector returns the user's suggestions, so
- * this should be passed as an address too.
- * extn0 ...
- * extn4 There are 5 extension text variables. These
- * should all be 3 characters long (plus the
- * terminator of course) and should not include
- * the '.' (dot) which normally preceeds an
- * extension. The first three will not be
- * changed by the selector and so may be defined
- * as constants in the calling line if desired.
- * The last two will be modified by the selector
- * and thus must be defined as real variables.
- * In all cases, the string must have all 3
- * characters defined (use trailing blanks or
- * underscores for short extensions). A '*'
- * will match anything; a '?' in any position
- * will match any character in that position.
- * fullname This is where the selector returns the user's
- * selected name and path. The string should be
- * long enough to hold the largest anticipated
- * string. The returned string will include
- * the drive specifier (i.e. A:), the full path
- * specified, and the file name itself.
- */
- int
- fsel(const char *title, /* I display title for box */
- char *path, /* IO initial path spec \ ... \ no drive; returns selected path */
- int *driv, /* IO selects drive -1=default 0=A: .. 5=F: */
- int *sextn, /* IO bitmap selected extn boxes :
- * 0x0001 = extn0 0x0002 = extn1 0x0004 = extn2
- * 0x0008 = extn3 0x0010 = extn4
- */
- char *extn0,
- char *extn1, /* I extension text not including "." for each of 1st 3 extn boxes */
- char *extn2, /* NOTE for all 5 boxes this should be 3 chars long, even if spaces */
- char *extn3,
- char *extn4, /* IO extension text for last 2 extn boxes (editable) */
- char *fullname) /* O returns complete path and file */
-
- {
-
- struct finfo files[MAXFILES]; /* holds name, extn, dir for all files */
-
- char newname[12], /* holds user-typed name */
- fnam[13], /* will build return filename here */
- c,
- drivs[3], /* current dir as string i.e. "B:" */
- dispath[17]; /* displayable pathname (trunc to 16 chars max) */
-
- int i,fp,ret,x,y,w,h;
- int action, /* flag */
- button, /* button code from dialog box */
- slidpsn, /* slider position 0-1000 */
- goodfiles[MAXFILES], /* has indices into 'files[]' of files matching extn specifications */
- numfiles, /* total number of files in 'files[]' */
- numgood, /* number of files noted in 'goodfiles[]' */
- curfirst, /* index into 'goodfiles[]' of first displayable file */
- hchar, /* height of character in pixels */
- my, /* mouse position y coordinate */
- doubleclick, /* TRUE if double-clicked on item, else FALSE */
- editfield; /* index of field to edit */
- int t; /* holds drivemap */
-
- /*
- * On the very first call to this subroutine we must do some
- * setup stuff... Primarily adjustments to the resource table
- * to adjust for screen resolution, and to adjust element locations
- * which do not live on even character boundaries.
- */
- if (firstcall) {
- firstcall = FALSE;
-
- for(i=0; i<=HIGH(rs_object); i++)
- rsrc_obfix(rs_object,i); /* chg coord from char to pixel */
-
- /*
- * also adjust size of SLIDBOX and xxARROWs into half-char sizes
- * because 1 char tall is too short to allow boxchar to display the arrows,
- * but 2 chars tall looks silly.
- */
- i=graf_handle(&ret,&hchar,&ret,&ret);
- rs_object[UARROW].ob_height += hchar/2;
- rs_object[DARROW].ob_y += hchar/2;
- rs_object[DARROW].ob_height += hchar/2;
- rs_object[SLIDBOX].ob_y += hchar/2;
-
- /*
- * and similarly, adjust position of filenames in menu box
- * so that 9 fit nicely into a box that tightly fits 10
- */
- for (i=0; i<WINDSIZE; i++) {
- rs_object[FNAM1+i].ob_y += hchar/2;
- } /* for */
- } /* if (firstcall) ... */
-
- strcpy(newname,"___________");
- rs_tedinfo[0].te_ptext = newname;
- rs_tedinfo[1].te_ptext = extn0 ;
- rs_tedinfo[2].te_ptext = extn1 ;
- rs_tedinfo[3].te_ptext = extn2 ;
- rs_tedinfo[4].te_ptext = extn3 ;
- rs_tedinfo[5].te_ptext = extn4 ;
- rs_tedinfo[6].te_ptext = dispath ;
-
-
- for (i=0; i<=HIGH(rs_tedinfo); i++) {
- rs_tedinfo[i].te_txtlen = strlen(rs_tedinfo[i].te_ptext) + 1 ;
- }
-
- rs_object[1].ob_spec = (unsigned long)title;
- FS_pathtrunc(dispath,path);
- for (i=0; i<WINDSIZE; i++) strcpy(&file_ids[i][0]," ");
- editfield = NEWNAME;
-
- /*
- * If user passed blanks for editable extensions, this is good
- * but it will look funny -- put in initial underscores instead,
- * also if he just passed unitialized (empty) string do it too.
- * We must assume that string will be long enough...
- */
- if((extn3[0] == ' ') OR (strlen(extn3) == 0)) strcpy(extn3,"___");
- if((extn4[0] == ' ') OR (strlen(extn4) == 0)) strcpy(extn4,"___");
-
- if (*sextn & 0x0001) rs_object[SLEXTN0].ob_state |= SELECTED;
- if (*sextn & 0x0002) rs_object[SLEXTN1].ob_state |= SELECTED;
- if (*sextn & 0x0004) rs_object[SLEXTN2].ob_state |= SELECTED;
- if (*sextn & 0x0008) rs_object[SLEXTN3].ob_state |= SELECTED;
- if (*sextn & 0x0010) rs_object[SLEXTN4].ob_state |= SELECTED;
-
- if (*driv == -1) *driv = Dgetdrv(); /* get cur logged drive if needed */
- rs_object[(*driv)+DRVA].ob_state |= SELECTED;
- drivs[0] = (*driv) +'A' ; drivs[1] = ':' ; drivs[2] = '\0' ;
-
- t = Drvmap();
- if ((t & 0x01) == 0) rs_object[DRVA].ob_state = DISABLED;
- if ((t & 0x02) == 0) rs_object[DRVB].ob_state = DISABLED;
- if ((t & 0x04) == 0) rs_object[DRVC].ob_state = DISABLED;
- if ((t & 0x08) == 0) rs_object[DRVD].ob_state = DISABLED;
- if ((t & 0x10) == 0) rs_object[DRVE].ob_state = DISABLED;
- if ((t & 0x20) == 0) rs_object[DRVF].ob_state = DISABLED;
-
- form_center (&rs_object,&xdial,&ydial,&wdial,&hdial);
- x=y=w=h=0;
- form_dial (0,x,y,w,h,xdial,ydial,wdial,hdial); /* reserve room */
- form_dial (1,x,y,w,h,xdial,ydial,wdial,hdial); /* grow box */
- objc_draw (&rs_object,0,2,xdial,ydial,wdial,hdial); /* draw the dialog box */
-
-
-
-
- FS_dir_read(drivs, path, files, &numfiles, dispath);
- FS_dir_select_good(*sextn,extn0,extn1,extn2,extn3,extn4,
- files, numfiles, goodfiles, &numgood, &curfirst);
- FS_calc_slid_box(numgood,curfirst,FALSE); /* calculate initial slider position */
-
- FS_dir_dis(files,goodfiles,numgood,curfirst);
-
- action = CONTINUE; /* look for new button press */
- while (action == CONTINUE) { /* loop while operator plays */
-
- if (rs_object[SLEXTN3].ob_state & SELECTED) /* setup status of (SL)EXTN3 click-ability */
- rs_object[EXTN3].ob_flags = TOUCHEXIT;
- else
- rs_object[EXTN3].ob_flags = EDITABLE;
-
- if (rs_object[SLEXTN4].ob_state & SELECTED) /* setup status of (SL)EXTN4 click-ability */
- rs_object[EXTN4].ob_flags = TOUCHEXIT;
- else
- rs_object[EXTN4].ob_flags = EDITABLE;
-
- button = form_do(&rs_object,editfield); /* manage user's actions until a button press */
- if (button & 0x8000) { /* if double-click ... */
- doubleclick = TRUE;
- button &= ~0x8000; /* (remove double-click bit from botton code) */
- }
- else
- doubleclick = FALSE;
-
- switch (button) { /* now prepare to act upon user's request */
- case CANCBUT: action = QUIT; rs_object[CANCBUT].ob_state &= ~SELECTED; break;
- case OKBUT: action = QUIT; rs_object[OKBUT].ob_state &= ~SELECTED; break;
-
- case DRVA:
- case DRVB:
- case DRVC:
- case DRVD:
- case DRVE:
- case DRVF: *driv = button - DRVA;
- drivs[0] = (*driv) + 'A'; drivs[1] = ':'; drivs[2] = '\0';
- strcpy(path,"\\");
- FS_pathtrunc(dispath,path);
- FS_dir_read(drivs,path,files,&numfiles,dispath);
- FS_dir_select_good(*sextn,extn0,extn1,extn2,extn3,extn4,
- files,numfiles,goodfiles,&numgood,&curfirst);
- FS_dir_dis(files,goodfiles,numgood,curfirst);
- FS_setname(-1,newname);
- break;
-
- case SLEXTN0:
- case SLEXTN1:
- case SLEXTN2:
- case SLEXTN3:
- case SLEXTN4: i = 0x01 << (button - SLEXTN0);
- *sextn ^= i ;
- FS_dir_select_good(*sextn,extn0,extn1,extn2,extn3,extn4,
- files,numfiles,goodfiles,&numgood,&curfirst);
- FS_dir_dis(files,goodfiles,numgood,curfirst);
- FS_setname(-1,newname);
- break;
-
- case FNAM1:
- case FNAM2:
- case FNAM3:
- case FNAM4:
- case FNAM5:
- case FNAM6:
- case FNAM7:
- case FNAM8:
- case FNAM9: i = button - FNAM1;
- fp= goodfiles[curfirst+i] ; /* (fp points into files[]) */
- if (files[fp].dirflag) { /* if a directory of any flavor */
- if (strcmp(files[fp].name,".") == 0) /* current directory */
- /* do nothing special */ ;
- else if (strcmp(files[fp].name,"..") == 0) { /* parent directory */
- FS_path_shorten(path,dispath);
- FS_dir_read(drivs,path,files,&numfiles,dispath);
- FS_dir_select_good(*sextn,extn0,extn1,extn2,extn3,extn4,
- files,numfiles,goodfiles,&numgood,&curfirst);
- }
- else { /* another directory */
- FS_path_lengthen(path,fp,files,dispath);
- FS_dir_read(drivs,path,files,&numfiles,dispath);
- FS_dir_select_good(*sextn,extn0,extn1,extn2,extn3,extn4,
- files,numfiles,goodfiles,&numgood,&curfirst);
- }
- FS_dir_dis(files,goodfiles,numgood,curfirst); /* then always display the selected directory */
- FS_setname(-1,newname);
- } /* end of 'if a directory' stuff */
- else { /* here it must be just a file */
- FS_setname(i,newname);
- if (doubleclick) { /* a doubleclick causes default OKBUT too */
- action = QUIT;
- button = OKBUT;
- }
- }
- break;
- case MVSLIDE: if (rs_object[SLIDBOX].ob_height==rs_object[MVSLIDE].ob_height) break; /* do nothing if full size */
- slidpsn = graf_slidebox(&rs_object,SLIDBOX,MVSLIDE,1);
- FS_calc_curfirst(slidpsn,numgood,&curfirst);
- FS_calc_slid_box(numgood,curfirst,TRUE);
- FS_dir_dis(files,goodfiles,numgood,curfirst);
- FS_setname(-1,newname);
- break;
- case SLIDBOX: graf_mkstate(&ret,&my,&ret,&ret);
- if (my > (ydial+rs_object[SLIDBOX].ob_y+rs_object[MVSLIDE].ob_y))
- FS_shift_curfirst(WINDSIZE,numgood,&curfirst);
- else
- FS_shift_curfirst(-WINDSIZE,numgood,&curfirst);
- FS_calc_slid_box(numgood,curfirst,TRUE);
- FS_dir_dis(files,goodfiles,numgood,curfirst);
- FS_setname(-1,newname);
- break;
- case UARROW: FS_shift_curfirst(-1,numgood,&curfirst);
- FS_calc_slid_box(numgood,curfirst,TRUE);
- FS_dir_dis(files,goodfiles,numgood,curfirst);
- FS_setname(-1,newname);
- break;
- case DARROW: FS_shift_curfirst(1,numgood,&curfirst);
- FS_calc_slid_box(numgood,curfirst,TRUE);
- FS_dir_dis(files,goodfiles,numgood,curfirst);
- FS_setname(-1,newname);
- break;
-
- /*
- * to get to EXTN3 then EXTN3 must have been TOUCHEXIT
- * which means that SLEXTN3 must have been SELECTED.
- * When we touched on the EXTN3 field we signify that we
- * want to edit it -- therefore we unSELECT the box so
- * that we can force a directory read when it next gets selected.
- */
- case EXTN3: rs_object[EXTN3].ob_flags = EDITABLE;
- objc_change(&rs_object,SLEXTN3,0,xdial,ydial,wdial,hdial,NORMAL,1);
- *sextn &= ~0x0008;
- editfield = EXTN3;
- break;
-
- /* similar logic here... */
- case EXTN4: rs_object[EXTN4].ob_flags = EDITABLE;
- objc_change(&rs_object,SLEXTN4,0,xdial,ydial,wdial,hdial,NORMAL,1);
- *sextn &= ~0x0010;
- editfield = EXTN4;
- break;
- } /* end of switch(button) */
- } /* end of while(action) */
-
- form_dial (2,x,y,w,h,xdial,ydial,wdial,hdial); /* shrink dialog box */
- form_dial (3,x,y,w,h,xdial,ydial,wdial,hdial); /* release its room */
-
- for (i=0; i<8; i++) { /* build formatted filename from newname */
- if ((c=newname[i]) == ' ') break ; /* (scan name part until ends at space */
- if ( c == '_' ) break; /* (also stops at _ in case no name was ever selected! */
- fnam[i] = c;
- fnam[i+1] = '\0';
- }
- if((newname[8] != ' ') AND (newname[8] != '_')) { /* (if there is an extension) */
- fnam[i++] = '.';
- fnam[i] = '\0';
- strcat(&fnam[i],&newname[8]);
- }
-
- strcpy(fullname,drivs); /* finally, build a returnable name with full path info too */
- strcat(fullname,path);
- strcat(fullname,fnam);
-
- if (button == CANCBUT) return (0); /* then return */
- return(1);
- } /* fsel() */
-
-
- /************************************************************
- * function FS_shift_curfirst() is called when the slider
- * is moved by an arrow key or a pageup/pagedn request.
- * it returns a new value for curfirst (index into goodfiles)
- */
- PRIVATE void
- FS_shift_curfirst(int inc, /* typically -1,1 (arrow), -9,+9 pagedn,pageup */
- int numgood, /* total number of good files */
- int *curfirst) /* returns new value for curfirst */
- {
- *curfirst += inc; /* change it as requested */
-
- /* then fix it if necessary */
- if (*curfirst > (numgood-WINDSIZE)) *curfirst = numgood-WINDSIZE;
- if (*curfirst < 0) *curfirst = 0;
- } /* FS_shift_curfirst() */
-
-
- /*********************************************************
- * function FS_calc_curfirst() is called after
- * a boxslide operation to find new value for curfirst.
- */
- PRIVATE void
- FS_calc_curfirst(int slidpsn, /* slider psn as returned from graf_slidbox 0-1000 */
- int numgood, /* total number of good files */
- int *curfirst) /* returned index into goodfiles */
- {
- *curfirst = (numgood * (slidpsn/10)) / 100 ; /* funny scaling to avoid arith overflow */
- if (*curfirst > (numgood - WINDSIZE)) *curfirst = numgood - WINDSIZE;
- } /* FS_calc_curfirst() */
-
-
- /*****************************************************
- * function FS_calc_slid_box() is called to calculate
- * new dimensions for the moving box, and draw it if necessary.
- */
- PRIVATE void
- FS_calc_slid_box(int numgood, /* number of good files */
- int curfirst, /* index into goodfiles[] */
- BOOL drawit) /* FALSE = don't draw, TRUE = please draw */
- {
- if (numgood <= WINDSIZE) { /* then sliding box is full size */
- rs_object[MVSLIDE].ob_y = 0; /* position at top (rel to parent) */
- rs_object[MVSLIDE].ob_height = rs_object[SLIDBOX].ob_height;
- }
- else {
- rs_object[MVSLIDE].ob_height = (rs_object[SLIDBOX].ob_height * WINDSIZE) / numgood ;
- rs_object[MVSLIDE].ob_y = (rs_object[SLIDBOX].ob_height * curfirst) / numgood ;
- }
-
- if (drawit) objc_draw(&rs_object,SLIDBOX,2,xdial,ydial,wdial,hdial);
- } /* FS_calc_slid_box() */
-
-
- /***************************************************************
- * function FS_setname() sets a filename or blanks into the NEWNAME field
- * if i== -1 then blanks are set, otherwise file_ids[i] is set
- */
- PRIVATE void FS_setname( int i, char *newname)
- {
- if (i == -1)
- strcpy(newname,"___________");
- else {
- strncpy(newname,&file_ids[i][2],8);
- strncpy(&newname[8],&file_ids[i][11],3);
- }
- objc_draw(&rs_object,NEWNAME,1,xdial,ydial,wdial,hdial);
- } /* FS_setname() */
-
-
- /***************************************
- * function FS_dir_read() reads specified directory
- * and stores names in 'files' array. Also adjusts numfiles.
- * function returns 0 on error 1 on success
- */
- PRIVATE int FS_dir_read(char *drivs, char *path, struct finfo files[],
- int *numfiles, char *dispath)
- {
- char fullname[14]; /* full name of file from dta */
- int dotat,error,i,numdirs,exch;
- char fullpath[80]; /* full path spec with driv, pathlist, and *.* */
- struct _dta *dtap;
-
- *numfiles = 0; /* no files found yet */
- dtap = (struct _dta *)Fgetdta();
-
- do {
- strcpy(fullpath, drivs);
- strcat(fullpath, path);
- strcat(fullpath, "*.*");
- error = d_First(drivs, path, FA_DIR);
- if (error == -33) {
- i = form_alert(2,"[1][You have specified either|an empty disk or a nonexistant path...][CONTINUE|RETRY|BACKUP PATH]");
- switch(i) {
- case 1: return(1); /* quit indicating success (?) */
- case 2: break; /* just do it again */
- case 3: FS_path_shorten(path,dispath);
- }
- }
- else if (error != 0) {
- char emsg[80];
- sprintf( emsg, "[1][%s|%s][QUIT]", sys_errlist[-error], fullpath);
- form_alert(1,emsg);
- exit(1); /* quit */
- } /* if */
- } while (error == -33);
-
- while (error == 0) {
- strcpy(fullname,dtap->dta_name);
- if(fullname[0] == '.') { /* then a directory . or .. */
- strcpy(files[*numfiles].name,fullname);
- strcpy(files[*numfiles].extn,"");
- }
- else { /* a real file */
-
- dotat = FS_find_last_delim('.',fullname);
- if (dotat == -1) {
- strcpy(files[*numfiles].extn,"");
- strcpy(files[*numfiles].name,fullname);
- }
- else {
- strcpy(files[*numfiles].extn,&fullname[dotat+1]);
- strncpy(files[*numfiles].name,fullname,dotat);
- files[*numfiles].name[dotat] = '\0';
- }
- }
- files[*numfiles].dirflag = (dtap->dta_attribute & FA_DIR) != 0;
- (*numfiles)++; /* count the discovered file */
- if (*numfiles > MAXFILES-1) { /* is this possible??? */
- *numfiles = MAXFILES-1; /* if so, just ignore later files */
- return(1); /* kinda sloppy huh ??? */
- }
- error = d_Next(); /* then look for another */
- } /* while */
-
- /* now find all directories and put at beginning of list */
- numdirs = 0;
- for (i=0; i< *numfiles; i++) {
- if(files[i].dirflag) {
- FS_exchinfo(&files[numdirs],&files[i]); /* if dir, swap to beginning of list */
- numdirs++; /* and count it */
- }
- }
-
- /* now sort the directories */
- if ((numdirs) > 1) {
- do {
- exch = FALSE;
- for(i=0; i<numdirs-1; i++) { /* for all directories */
- if(strcmp(files[i].name,files[i+1].name) > 0) {
- FS_exchinfo(&files[i],&files[i+1]);
- }
- }
- } while (exch == TRUE);
- }
-
- /* and now sort real files */
- if ((*numfiles-numdirs) > 1) {
- do {
- exch = FALSE;
- for(i=numdirs; i< *numfiles-1; i++) { /* for all files */
- if(strcmp(files[i].name,files[i+1].name) > 0) {
- FS_exchinfo(&files[i],&files[i+1]);
- exch = TRUE;
- }
- }
- } while (exch == TRUE);
- }
-
- /* all done so return status */
- if (error == -ENMFILES) return (1) ; /* success if error = "no more files" */
- return(0); /* else a problem */
- } /* FS_dir_read() */
-
-
- /**************************************************
- * function FS_dir_select_good() scans files[] for files matching at least one of
- * specified extensions. Counts matches in numgood, stores index (into files[])
- * in goodfiles[]. Also sets curfirst = 0 so later display will start at beginning.
- */
- PRIVATE void
- FS_dir_select_good( int sextn, /* the mask specifying checkable extensions */
- const char *extn0, /* the extensions to try matching */
- const char *extn1,
- const char *extn2,
- char *extn3,
- char *extn4,
- struct finfo files[],
- int numfiles,
- int goodfiles[],
- int *numgood,
- int *curfirst)
- {
- int i;
-
- *curfirst = 0;
- *numgood = 0;
-
- for (i=0; i<numfiles; i++) { /* always match directories */
- if(files[i].dirflag) {
- goodfiles[(*numgood)++] = i;
- continue;
- }
- if((sextn & 0x01) AND FS_wildmatch(extn0,files[i].extn)) {
- goodfiles[(*numgood)++] = i;
- continue;
- }
- if((sextn & 0x02) AND FS_wildmatch(extn1,files[i].extn)) {
- goodfiles[(*numgood)++] = i;
- continue;
- }
- if((sextn & 0x04) AND FS_wildmatch(extn2,files[i].extn)) {
- goodfiles[(*numgood)++] = i;
- continue;
- }
- if((sextn & 0x08) AND FS_wildmatch(extn3,files[i].extn)) {
- goodfiles[(*numgood)++] = i;
- continue;
- }
- if((sextn & 0x10) AND FS_wildmatch(extn4,files[i].extn)) {
- goodfiles[(*numgood)++] = i;
- continue;
- }
- }
- }
-
- /*
- * function FS_dir_dis() displays current directory in window. It displays
- * at max WINDSIZE names, starting at 'curfirst' in files[].
- */
- PRIVATE void
- FS_dir_dis( struct finfo files[],
- int goodfiles[],
- int numgood,
- int curfirst)
- {
- int i,j;
-
- /* first, clear out display strings */
- for (i=0; i<WINDSIZE; i++) {
- for(j=0; j<16; j++)
- file_ids[i][j] = ' ';
- file_ids[i][16] = '\0';
- }
-
- /* now build at most WINDSIZE filenames */
- for (i=0,j=curfirst; i<WINDSIZE; i++,j++) {
- if (j >= numgood) break; /* in case not enough good files to fill window */
- FS_strxcpy(&file_ids[i][2],files[goodfiles[j]].name); /* put in basic filename */
- if (strlen(files[goodfiles[j]].extn) > 0) { /* if there is an extension... */
- file_ids[i][10] = '.';
- FS_strxcpy(&file_ids[i][11],files[goodfiles[j]].extn);
- }
- if (files[goodfiles[j]].dirflag)
- file_ids[i][0] = DIAMOND_THINGY; /* put in funny box if its a directory */
- }
-
- /* and finally 'print' all to screen */
- for (i=0; i< WINDSIZE; i++)
- rs_object[FNAM1+i].ob_state = NORMAL; /* unselect all filenames */
- objc_draw(&rs_object,FILEBOX,2,xdial,ydial,wdial,hdial); /* blank the FILEBOX then write in all filenames */
- FS_calc_slid_box(numgood,curfirst,1); /* redraw sliding box too */
- objc_draw(&rs_object,TOPBAR, 0,xdial,ydial,wdial,hdial); /* redraw TOPBAR to erase old path name */
- objc_draw(&rs_object,TOPTEXT,0,xdial,ydial,wdial,hdial); /* then redraw TOPTEXT so that new path is shown */
- }
-
-
- /*******************************************************
- * function FS_path_lengthen() is called to add a newly
- * selected name to the current pathlist. It is assumed that
- * the newly selected name is a directory...
- */
- PRIVATE void
- FS_path_lengthen( char *path, /* the current path name (ends with '\') */
- int index, /* index into FS_files[] of name to add */
- struct finfo files[],
- char * dispath) /* the truncated displayable version of same */
- {
- strcat(path,files[index].name); /* add the name itself */
- if (strlen(files[index].extn) > 0) { /* (if there is an extension */
- strcat(path,"."); /* then append it */
- strcat(path,files[index].extn);
- }
- strcat(path,"\\"); /* and put on trailing backslash */
- FS_pathtrunc(dispath,path); /* make displayable version */
- } /* FS_path_lengthen() */
-
- /*
- * function FS_path_shorten() shortens the current path.
- * It is called after click on ".."
- * Note that the path must always start and end with a '\'
- * character (will always have a length of at least 1).
- */
- PRIVATE void FS_path_shorten( char *path, char *dispath)
- {
- int len,i;
-
- len=strlen(path);
- if (len == 1) return; /* already minimum path */
- i=len-2; /* points at char before trailing slash */
- while(path[i] != '\\') i-- ; /* keep looking for a slash */
- path[i+1] = '\0' ; /* and put a terminator after it */
- FS_pathtrunc(dispath,path); /* make displayable version */
- }
-
- /*
- * function pathtrunc() truncates real pathname into shorter displayable version
- */
- PRIVATE void FS_pathtrunc( char *dpath, /* the output (destination) string */
- const char *spath) /* the (maybe too long) source str */
- {
- int slen,i,is,id;
-
- if((slen=strlen(spath)) <= 16) strcpy(dpath,spath); /* the trivial case */
- else {
- is = slen - 1 ; /* index of last char in string */
- id = 15 ; /* last position in destination string */
- for(i=0; i<14; i++) /* copy 14 chars into 16 char field */
- dpath[id--] = spath[is--];
- dpath[0] = '<'; /* and put little flags at beginning */
- dpath[1] = '<';
- }
- }
-
- /*
- * function FS_wildmatch() checks a specified extension
- * against a mask value for match, and returns TRUE if matched, else FALSE.
- * Cases causing match are as follows:
- * exact match
- * mask value is "*"
- * match on all existing characters, with any '?' in mask matching anything
- * Note that the mask value may have trailing spaces (" ") or underbars ("_") as
- * a result of the object template process. These are considered junk and are
- * removed from the comparison process.
- */
- PRIVATE BOOL FS_wildmatch( const char *mask, const char *candidate)
- {
- int masklen,i;
-
- if(mask[0]=='*') return(TRUE); /* a '*' in mask matches anything */
-
- masklen = strlen(mask); /* will elim trailing spaces and underbars */
- for(i=masklen-1; i>0; i--) /* check all but first char to see if it is ignorable */
- if((mask[i]==' ') OR (mask[i]=='_')) masklen=i; /* adjust length word to effect ignorance */
- if(strlen(candidate) > masklen) return(FALSE); /* candidate .OLD should not match mask .O */
-
- for(i=0; i<masklen; i++) { /* now look at all valid chars to check for match */
- if(mask[i] == '?') continue; /* a '?' in mask matches anything in that position */
- if(toupper(mask[i]) != toupper(candidate[i])) return(FALSE); /* oops -- no match */
- }
-
- return(TRUE); /* must have matched ! */
- }
-
-
-
- /*
- * function FS_exchinfo() exchanges contents of two 'finfo' style structures
- */
- PRIVATE void FS_exchinfo( struct finfo *x, struct finfo *y)
- {
- struct finfo t;
-
- t = *x; /* caution -- */
- *x = *y; /* this all-in-one assignment is an extension that works in MM C */
- *y = t; /* other C's take care ... */
- }
-
-
- PRIVATE int FS_find_last_delim(char delim, char *string)
- {
- int i,spot;
-
- spot = -1;
- for (i=0; i<strlen(string); i++)
- if (string[i] == delim) spot = i;
- return(spot);
- }
-
- /*
- * function FS_strxcpy() is just like strcpy except it does not copy
- * the terminating \0
- */
- PRIVATE void FS_strxcpy(char *dest, const char *sour)
- {
- char c;
- while ((c=*sour++) != '\0') *dest++ = c ;
- }
-
- /************************* end of fsel.c ************************/
-